#include "graphics/gradients.hpp"

namespace editor::gradient {

Stop::Stop(const float t, const uint8_t r, const uint8_t g, const uint8_t b)
    : t{t}
    , color{
        static_cast<float>(r) / 255.0f,
        static_cast<float>(g) / 255.0f,
        static_cast<float>(b) / 255.0f
    }
{
}

Palette::Palette(const char* name, const std::initializer_list<Stop> stops)
    : name {name}
    , stops{stops}
{
}

auto Palette::get(const float t) const -> glm::vec3
{
    if (t < 0.0f) {
        return glm::vec3{1.0f, 0.0f, 0.0f};
    }
    if (t > 1.0f) {
        return glm::vec3{1.0f, 0.0f, 1.0f};
    }
    for (size_t i = 0; i < stops.size() - 1; ++i) {
        const auto& stop0 = stops[i    ];
        const auto& stop1 = stops[i + 1];
        const float t0    = stop0.t;
        const float t1    = stop1.t;
        if ((t >= t0) && (t <= t1)) {
            const float t_length     = t1 - t0;
            const float normalized_t = (t - t0) / t_length;
            const auto  color0       = stop0.color;
            const auto  color1       = stop1.color;
            return glm::mix(color0, color1, normalized_t);
        }
    }
    return glm::vec3{0.0f};
}

const Palette cool             { "cool",             {{0.0f, 125,  0,179},{0.130f,116,  0,218},{0.250f, 98, 74,237},{0.380f, 68,146,231},{0.500f,  0,204,197},{0.630f,  0,247,146},{0.750f,  0,255, 88},{0.880f, 40,255,  8},{1.000f,147,255,  0}}};
const Palette cool_simple      { "cool-simple",      {{0.0f,   0,255,255},{1.000f,255,  0,255}}};
const Palette spring           { "spring",           {{0.0f, 255,  0,255},{1.000f,255,255,  0}}};
const Palette summer           { "summer",           {{0.0f,   0,128,102},{1.000f,255,255,102}}};
const Palette autumn           { "autumn",           {{0.0f, 255,  0,  0},{1.000f,255,255,  0}}};
const Palette winter           { "winter",           {{0.0f,   0,  0,255},{1.000f,  0,255,128}}};
const Palette greys            { "greys",            {{0.0f,   0,  0,  0},{1.000f,255,255,255}}};
const Palette bluered          { "bluered",          {{0.0f,   0,  0,255},{1.000f,255,  0,  0}}};
const Palette copper           { "copper",           {{0.0f,   0,  0,  0},{0.804f,255,160,102},{1.000f,255,199,127}}};
const Palette hot              { "hot",              {{0.0f,   0,  0,  0},{0.300f,230,  0,  0},{0.600f,255,210,  0},{1.000f,255,255,255}}};
const Palette bone             { "bone",             {{0.0f,   0,  0,  0},{0.376f, 84, 84,116},{0.753f,169,200,200},{1.000f,255,255,255}}};
const Palette blackbody        { "blackbody",        {{0.0f,   0,  0,  0},{0.200f,230,  0,  0},{0.400f,230,210,  0},{0.700f,255,255,255},{1.000f,160,200,255}}};
const Palette portland         { "portland",         {{0.0f,  12, 51,131},{0.250f, 10,136,186},{0.500f,242,211, 56},{0.750f,242,143, 56},{1.000f,217, 30, 30}}};
const Palette electric         { "electric",         {{0.0f,   0,  0,  0},{0.150f, 30,  0,100},{0.400f,120,  0,100},{0.600f,160, 90,  0},{0.800f,230,200,  0},{1.000f,255,250,220}}};
const Palette earth            { "earth",            {{0.0f,   0,  0,130},{0.100f,  0,180,180},{0.200f, 40,210, 40},{0.400f,230,230, 50},{0.600f,120, 70, 20},{1.000f,255,255,255}}};
const Palette jet              { "jet",              {{0.0f,   0,  0,131},{0.125f,  0, 60,170},{0.375f,  5,255,255},{0.625f,255,255,  0},{0.875f,250,  0,  0},{1.000f,128,  0,  0}}};
const Palette rdbu             { "rdbu",             {{0.0f,   5, 10,172},{0.350f,106,137,247},{0.500f,190,190,190},{0.600f,220,170,132},{0.700f,230,145, 90},{1.000f,178, 10, 28}}};
const Palette yignbu           { "yignbu",           {{0.0f,   8, 29, 88},{0.125f, 37, 52,148},{0.250f, 34, 94,168},{0.375f, 29,145,192},{0.500f, 65,182,196},{0.625f,127,205,187},{0.750f,199,233,180},{0.875f,237,248,217},{1.000f,255,255,217}}};
const Palette greens           { "greens",           {{0.0f,   0, 68, 27},{0.125f,  0,109, 44},{0.250f, 35,139, 69},{0.375f, 65,171, 93},{0.500f,116,196,118},{0.625f,161,217,155},{0.750f,199,233,192},{0.875f,229,245,224},{1.000f,247,252,245}}};
const Palette yiorrd           { "yiorrd",           {{0.0f, 128,  0, 38},{0.125f,189,  0, 38},{0.250f,227, 26, 28},{0.375f,252, 78, 42},{0.500f,253,141, 60},{0.625f,254,178, 76},{0.750f,254,217,118},{0.875f,255,237,160},{1.000f,255,255,204}}};
const Palette rainbow          { "rainbow",          {{0.0f, 150,  0, 90},{0.125f,  0,  0,200},{0.250f,  0, 25,255},{0.375f,  0,152,255},{0.500f, 44,255,150},{0.625f,151,255,  0},{0.750f,255,234,  0},{0.875f,255,111,  0},{1.000f,255,  0,  0}}};
const Palette viridis          { "viridis",          {{0.0f,  68,  1, 84},{0.130f, 71, 44,122},{0.250f, 59, 81,139},{0.380f, 44,113,142},{0.500f, 33,144,141},{0.630f, 39,173,129},{0.750f, 92,200, 99},{0.880f,170,220, 50},{1.000f,253,231, 37}}};
const Palette inferno          { "inferno",          {{0.0f,   0,  0,  4},{0.130f, 31, 12, 72},{0.250f, 85, 15,109},{0.380f,136, 34,106},{0.500f,186, 54, 85},{0.630f,227, 89, 51},{0.750f,249,140, 10},{0.880f,249,201, 50},{1.000f,252,255,164}}};
const Palette magma            { "magma",            {{0.0f,   0,  0,  4},{0.130f, 28, 16, 68},{0.250f, 79, 18,123},{0.380f,129, 37,129},{0.500f,181, 54,122},{0.630f,229, 80,100},{0.750f,251,135, 97},{0.880f,254,194,135},{1.000f,252,253,191}}};
const Palette plasma           { "plasma",           {{0.0f,  13,  8,135},{0.130f, 75,  3,161},{0.250f,125,  3,168},{0.380f,168, 34,150},{0.500f,203, 70,121},{0.630f,229,107, 93},{0.750f,248,148, 65},{0.880f,253,195, 40},{1.000f,240,249, 33}}};
const Palette warm             { "warm",             {{0.0f, 125,  0,179},{0.130f,172,  0,187},{0.250f,219,  0,170},{0.380f,255,  0,130},{0.500f,255, 63, 74},{0.630f,255,123,  0},{0.750f,234,176,  0},{0.880f,190,228,  0},{1.000f,147,255,  0}}};
const Palette bathymetry       { "bathymetry",       {{0.0f,  40, 26, 44},{0.130f, 59, 49, 90},{0.250f, 64, 76,139},{0.380f, 63,110,151},{0.500f, 72,142,158},{0.630f, 85,174,163},{0.750f,120,206,163},{0.880f,187,230,172},{1.000f,253,254,204}}};
const Palette cdom             { "cdom",             {{0.0f,  47, 15, 62},{0.130f, 87, 23, 86},{0.250f,130, 28, 99},{0.380f,171, 41, 96},{0.500f,206, 67, 86},{0.630f,230,106, 84},{0.750f,242,149,103},{0.880f,249,193,135},{1.000f,254,237,176}}};
const Palette chlorophyll      { "chlorophyll",      {{0.0f,  18, 36, 20},{0.130f, 25, 63, 41},{0.250f, 24, 91, 59},{0.380f, 13,119, 72},{0.500f, 18,148, 80},{0.630f, 80,173, 89},{0.750f,132,196,122},{0.880f,175,221,162},{1.000f,215,249,208}}};
const Palette density          { "density",          {{0.0f,  54, 14, 36},{0.130f, 89, 23, 80},{0.250f,110, 45,132},{0.380f,120, 77,178},{0.500f,120,113,213},{0.630f,115,151,228},{0.750f,134,185,227},{0.880f,177,214,227},{1.000f,230,241,241}}};
const Palette freesurface_blue { "freesurface-blue", {{0.0f,  30,  4,110},{0.130f, 47, 14,176},{0.250f, 41, 45,236},{0.380f, 25, 99,212},{0.500f, 68,131,200},{0.630f,114,156,197},{0.750f,157,181,203},{0.880f,200,208,216},{1.000f,241,237,236}}};
const Palette freesurface_red  { "freesurface-red",  {{0.0f,  60,  9, 18},{0.130f,100, 17, 27},{0.250f,142, 20, 29},{0.380f,177, 43, 27},{0.500f,192, 87, 63},{0.630f,205,125,105},{0.750f,216,162,148},{0.880f,227,199,193},{1.000f,241,237,236}}};
const Palette oxygen           { "oxygen",           {{0.0f,  64,  5,  5},{0.130f,106,  6, 15},{0.250f,144, 26,  7},{0.380f,168, 64,  3},{0.500f,188,100,  4},{0.630f,206,136, 11},{0.750f,220,174, 25},{0.880f,231,215, 44},{1.000f,248,254,105}}};
const Palette par              { "par",              {{0.0f,  51, 20, 24},{0.130f, 90, 32, 35},{0.250f,129, 44, 34},{0.380f,159, 68, 25},{0.500f,182, 99, 19},{0.630f,199,134, 22},{0.750f,212,171, 35},{0.880f,221,210, 54},{1.000f,225,253, 75}}};
const Palette phase            { "phase",            {{0.0f, 145,105, 18},{0.130f,184, 71, 38},{0.250f,186, 58,115},{0.380f,160, 71,185},{0.500f,110, 97,218},{0.630f, 50,123,164},{0.750f, 31,131,110},{0.880f, 77,129, 34},{1.000f,145,105, 18}}};
const Palette salinity         { "salinity",         {{0.0f,  42, 24,108},{0.130f, 33, 50,162},{0.250f, 15, 90,145},{0.380f, 40,118,137},{0.500f, 59,146,135},{0.630f, 79,175,126},{0.750f,120,203,104},{0.880f,193,221,100},{1.000f,253,239,154}}};
const Palette temperature      { "temperature",      {{0.0f,   4, 35, 51},{0.130f, 23, 51,122},{0.250f, 85, 59,157},{0.380f,129, 79,143},{0.500f,175, 95,130},{0.630f,222,112,101},{0.750f,249,146, 66},{0.880f,249,196, 65},{1.000f,232,250, 91}}};
const Palette turbidity        { "turbidity",        {{0.0f,  34, 31, 27},{0.130f, 65, 50, 41},{0.250f, 98, 69, 52},{0.380f,131, 89, 57},{0.500f,161,112, 59},{0.630f,185,140, 66},{0.750f,202,174, 88},{0.880f,216,209,126},{1.000f,233,246,171}}};
const Palette velocity_blue    { "velocity-blue",    {{0.0f,  17, 32, 64},{0.130f, 35, 52,116},{0.250f, 29, 81,156},{0.380f, 31,113,162},{0.500f, 50,144,169},{0.630f, 87,173,176},{0.750f,149,196,189},{0.880f,203,221,211},{1.000f,254,251,230}}};
const Palette velocity_green   { "velocity-green",   {{0.0f,  23, 35, 19},{0.130f, 24, 64, 38},{0.250f, 11, 95, 45},{0.380f, 39,123, 35},{0.500f, 95,146, 12},{0.630f,152,165, 18},{0.750f,201,186, 69},{0.880f,233,216,137},{1.000f,255,253,205}}};
const Palette picnic           { "picnic",           {{0.0f,   0,  0,255},{0.100f, 51,153,255},{0.200f,102,204,255},{0.300f,153,204,255},{0.400f,204,204,255},{0.500f,255,255,255},{0.600f,255,204,255},{0.700f,255,153,255},{0.800f,255,102,204},{0.900f,255,102,102},{1.00f,255,  0,  0}}};
const Palette rainbow_soft     { "rainbow-soft",     {{0.0f, 125,  0,179},{0.100f,199,  0,180},{0.200f,255,  0,121},{0.300f,255,108,  0},{0.400f,222,194,  0},{0.500f,150,255,  0},{0.600f,  0,255, 55},{0.700f,  0,246,150},{0.800f, 50,167,222},{0.900f,103, 51,235},{1.00f,124,  0,186}}};
const Palette hsv              { "hsv",              {{0.0f, 255,  0,  0},{0.169f,253,255,  2},{0.173f,247,255,  2},{0.337f,  0,252,  4},{0.341f,  0,252, 10},{0.506f,  1,249,255},{0.671f,  2,  0,253},{0.675f,  8,  0,253},{0.839f,255,  0,251},{0.843f,255,  0,245},{1.00f,255,  0,  6}}};
const Palette cubehelix        { "cubehelix",        {{0.0f,   0,  0,  0},{0.070f, 22,  5, 59},{0.130f, 60,  4,105},{0.200f,109,  1,135},{0.270f,161,  0,147},{0.330f,210,  2,142},{0.400f,251, 11,123},{0.470f,255, 29, 97},{0.530f,255, 54, 69},{0.600f,255, 85, 46},{0.67f,255,120, 34},{0.73f,255,157, 37},{0.8f,241,191, 57},{0.87f,224,220, 93},{0.93f,218,241,142},{1.0f,227,253,198}}};

} // namespace editor::gradient
